package com.jason.base;

import com.baomidou.mybatisplus.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.SqlHelper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.jason.core.config.jwt.JwtUtil;
import com.jason.entity.SysUser;
import com.jason.service.ISysUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;

/**
 * author sj
 */
public class BaseServiceImpl<M extends BaseMapper<T>, T extends BaseModel> extends ServiceImpl<M, T> implements BaseService<T>  {


    @Autowired
    JwtUtil jwtUtil;

    @Autowired
    ISysUserService sysUserService;

    @Autowired
    private  HttpServletRequest request;

    /**
     * 通用查询分页方法
     * @param model
     * @return Page
     */
    public Page selectPage(T model){
        return selectPage(getPageInfo(model), getEntityWrapper(model, null));
    }

    /**
     * 通用查询列表方法
     * @param model
     * @return List
     */
    public List<T> selectList(T model){
        EntityWrapper<T> entityWrapper = new EntityWrapper<>();
        entityWrapper.setEntity(model);
        return selectList(entityWrapper);
    }

    /**
     * 通用查询单条方法
     * @param model
     * @return List
     */
    public T selectOne(T model){
        EntityWrapper<T> entityWrapper = new EntityWrapper<>();
        entityWrapper.setEntity(model);
        return selectOne(entityWrapper);
    }

    /**
     * 获取分页信息
     * @param model
     * @return Page
     */
    public Page<T> getPageInfo(T model){
        Page<T> page = new Page<>();
        if (model != null){
            int current = model.getCurrent();
            int size = model.getSize();
            String orderByField = model.getOrderByField();
            page = getPageInfo(current > 0 ? current : 1,
                    size > 0 ? size : 10,
                    StringUtils.isNotBlank(orderByField) ? orderByField : null,
                    model.isAsc());
        }
        return page;
    }

    /**
     * 获取自定义分页信息
     * @param current
     * @param size
     * @param orderByField
     * @param asc
     * @return Page
     */
    public Page<T> getPageInfo(int current, int size, String orderByField, boolean asc){
        Page<T> page = new Page<>();
        page.setCurrent(current > 0 ? current : 1);
        page.setSize(size > 0 ? size : 10);
        page.setOrderByField(StringUtils.isNotBlank(orderByField) ? orderByField : null);
        page.setAsc(asc);
        return page;
    }

    /**
     * 获取查询模板
     * 子类可重写该方法以自定义模板
     * @param model
     * @return EntityWrapper
     */
    public EntityWrapper<T> getEntityWrapper(T model, EntityWrapper<T> entityWrapper){
        if (entityWrapper == null){
            entityWrapper = new EntityWrapper<>();
        }
        entityWrapper.setEntity(model);
        return entityWrapper;
    }

    /**
     * 获取当前userId
     * @return
     */
    public Long getCurrentUserId(){
        String token = request.getHeader("Authorization");
        if (StringUtils.isNotBlank(token)){
            token = token.substring("Bearer ".length());
        } else{
            return null;
        }
        String username = jwtUtil.getUserNameFromToken(token);
        if (StringUtils.isEmpty(username)){
            return null;
        }
        SysUser sysUser=new SysUser();
        sysUser.setUsername(username);
        sysUser= sysUserService.selectOne(sysUser);
        Long id=sysUser.getId();
        return id;
    }

    /**
     * 批量添加或修改设置size
     * @param entityList
     * @return boolean
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean insertOrUpdateBatch(List<T> entityList) {
        try {
            Long id=getCurrentUserId();
            for(T t:entityList){
                if(t.getId()==null){
                    if (t.getCreatedBy() == null){
                        t.setCreatedBy(id);
                    }
                    if (t.getCreatedTime() == null){
                        t.setCreatedTime(new Date());
                    }
                }else{
                    if (t.getUpdatedBy() == null){
                        t.setUpdatedBy(id);
                    }
                    if (t.getUpdatedTime() == null){
                        t.setUpdatedTime(new Date());
                    }
                }
            }
            int listSize = entityList.size();
            if (listSize == 0){
                return true;
            }
            return insertOrUpdateBatch(entityList, listSize);
        } catch(Throwable e){
            throw new MybatisPlusException("Error: Cannot execute insertOrUpdateBatch Method. Cause", e);
        }
    }

    /**
     * 批量添加设置size
     * @param entityList
     * @return boolean
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean insertBatch(List<T> entityList) {
        try {
            Long id=getCurrentUserId();
            for(T t:entityList){
                if (t.getCreatedBy() == null){
                    t.setCreatedBy(id); 
                }
                if (t.getCreatedTime() == null){
                    t.setCreatedTime(new Date()); 
                }
            }
            int listSize = entityList.size();
            if (listSize == 0){
                return true;
            }
            return insertBatch(entityList, listSize);
        } catch(Throwable e){
            throw new MybatisPlusException("Error: Cannot execute insertBatch Method. Cause", e);
        }
    }


    /**
     * 添加设置操作用户
     * @param t
     * @return boolean
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean insertWithUser(T t) {
        try {
            Long id=getCurrentUserId();
            if (t.getCreatedBy() == null){
                t.setCreatedBy(id);
            }
            if (t.getCreatedTime() == null){
                t.setCreatedTime(new Date());
            }
            return insert(t);
        } catch(Throwable e){
            throw new MybatisPlusException("Error: Cannot execute insert Method. Cause", e);
        }
    }

    /**
     * 添加或修改设置操作用户
     * @param t
     * @return boolean
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean insertOrUpdateByUser(T t) {
        try {
            Long id=getCurrentUserId();
            if (t.getCreatedBy() == null){
                t.setCreatedBy(id);
            }
            if (t.getCreatedTime() == null){
                t.setCreatedTime(new Date());
            }
            if (t.getUpdatedBy() == null){
                t.setUpdatedBy(id);
            }
            if (t.getUpdatedTime() == null){
                t.setUpdatedTime(new Date());
            }
            return insertOrUpdate(t);
        } catch(Throwable e){
            throw new MybatisPlusException("Error: Cannot execute insert Method. Cause", e);
        }
    }

    /**
     * 修改设置操作用户
     * @param t
     * @return boolean
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean updateByUser(T t) {
        try {
            Long id=getCurrentUserId();
            if (t.getUpdatedBy() == null){
                t.setUpdatedBy(id);
            }
            if (t.getUpdatedTime() == null){
                t.setUpdatedTime(new Date());
            }
            return updateById(t);
        } catch(Throwable e){
            throw new MybatisPlusException("Error: Cannot execute insert Method. Cause", e);
        }
    }

    /**
     * 批量修改设置size
     * @param entityList
     * @return boolean
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean updateBatchById(List<T> entityList) {
        try {
            Long id=getCurrentUserId();
            for(T t:entityList){
                if (t.getUpdatedBy() == null){
                    t.setUpdatedBy(id);
                }
                if (t.getUpdatedTime() == null){
                    t.setUpdatedTime(new Date());
                }
            }
            int listSize = entityList.size();
            if (listSize == 0){
                return true;
            }
            return updateBatchById(entityList, listSize);
        } catch(Throwable e){
            throw new MybatisPlusException("Error: Cannot execute updateBatchById Method. Cause", e);
        }
    }


    @Transactional(rollbackFor = Exception.class)
    public boolean deleteBatchIds(Collection<? extends Serializable> idList) {
        if (idList.size() > 0){
            return SqlHelper.delBool(this.baseMapper.deleteBatchIds(idList));
        }
        return true;
    }

    /**
     * 删除并记录userId
     * @param t
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteByUser(T t) {
        try {
            Long id = getCurrentUserId();
            if (t.getUpdatedBy() == null){
                t.setUpdatedBy(id);
            }
            if (t.getUpdatedTime() == null){
                t.setUpdatedTime(new Date());
            }
            t.setDeletedFLag(1);
            return updateById(t);
        } catch(Throwable e){
            throw new MybatisPlusException("Error: Cannot execute deleteByUser Method. Cause", e);
        }
    }

    /**
     * 批量删除并记录userId
     * @param list
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteBatchIdsByUser(List<T> list) {
        try {
            Long id=getCurrentUserId();
            for(T t : list){
                if (t.getUpdatedBy() == null){
                    t.setUpdatedBy(id);
                }
                if (t.getUpdatedTime() == null){
                    t.setUpdatedTime(new Date());
                }
                t.setDeletedFLag(1);
            }
            int listSize = list.size();
            if (listSize == 0){
                return true;
            }
            return updateBatchById(list, listSize);
        } catch(Throwable e){
            throw new MybatisPlusException("Error: Cannot execute deleteBatchIdsByUser Method. Cause", e);
        }
    }



    /*public boolean deleteBatchIds(Collection<? extends Serializable> idList) {
        try {
            Long id=getCurrentUserId();
            List<T> list = new ArrayList<>();
            for(int i = 0; i < idList.size(); i++){
                t.setUpdatedBy(id);
                t.setUpdatedTime(new Date());
            }
            int listSize = entityList.size();
            if (listSize == 0){
                return true;
            }
            return updateBatchById(entityList, listSize);
        } catch(Throwable e){
            throw new MybatisPlusException("Error: Cannot execute updateBatchById Method. Cause", e);
        }
    }*/



}
